﻿using Snowflake.Core;
using System.Net;

namespace Kz.Telegram.Bot.Console.Helpers
{
    /// <summary>
    /// 雪花算法
    /// </summary>
    public class SnowflakeHelper
    {
        private static IdWorker _worker { get; set; }
        private static readonly object __lock = new();
        private static Random random = new Random();
        private const string EnvWorkdIdName = "SnowFlakeWorkId";

        public static long WorkId = 0;
        public static long DataCenterId = 0;

        /// <summary>
        /// 单例
        /// </summary>
        /// <param name="workId"></param>
        /// <param name="dataId"></param>
        /// <returns></returns>
        private static IdWorker Instance
        {
            get
            {
                if (_worker == null)
                {
                    lock (__lock)
                    {
                        if (_worker == null)
                        {
                            if (WorkId == 0)
                                WorkId = GetWorkId();
                            if (DataCenterId == 0)
                                DataCenterId = GetDataCenterId();

                            _worker = new IdWorker(WorkId, DataCenterId);
                        }
                    }
                }
                return _worker;
            }
        }

        /// <summary>
        /// 获取雪花ID
        /// </summary>
        /// <returns></returns>
        public static string NextId()
        {
            return Instance.NextId().ToString();
        }

        /// <summary>
        /// 获取workId
        /// </summary>
        /// <returns></returns>
        private static long GetWorkId()
        {
            try
            {
                string envId = Environment.GetEnvironmentVariable(EnvWorkdIdName, EnvironmentVariableTarget.Machine);
                var result = string.IsNullOrEmpty(envId) ? 0 : Convert.ToInt32(envId);
                if (result > 0)
                    return result;

                var address = Dns.GetHostEntry(Dns.GetHostName()).AddressList;
                var ip = address.Where(it => it.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork).FirstOrDefault().ToString();

                var sums = ip.Select(s => Convert.ToInt32(s)).Sum();
                result = sums % 32;
                if (result == 0)
                    result = random.Next(1, 32);
                return result;
            }
            catch (Exception)
            {
                return random.Next(1, 32);
            }
        }

        /// <summary>
        /// 获取DataCenterId
        /// </summary>
        /// <returns></returns>
        private static long GetDataCenterId()
        {
            try
            {
                var domainName = AppDomain.CurrentDomain.FriendlyName.Replace(".", "_");
                if (Enum.TryParse<AppDomainEnum>(domainName, true, out var result))
                {
                    return (int)result;
                }
                else
                {
                    return random.Next(1, 32);
                }
            }
            catch (Exception)
            {
                return random.Next(1, 32);
            }
        }
    }

    /// <summary>
    /// 项目数据中心Id
    /// </summary>
    public enum AppDomainEnum
    {
        DM_AICallCenter_WebApi = 1,
        DM_AICallCenter_WebManagerApi = 2,
        DM_AICallCenter_WebOpenApi = 3,
        DM_AICallCenter_WebRobotApi = 4,
        DM_AICallCenter_SeatsDataService = 5,
        DM_AICallCenter_QuartzJobs = 6,
        DM_AICallCenter_WebExternalApi = 7,
        DM_AICallCenter_WorkMobileDataService = 8
    }
}